package com.pai4j.ugc.repository.dao;
import com.pai4j.ugc.repository.entity.ChatMessageEntity;
import com.pai4j.ugc.repository.entity.InteractionMessageEntity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * 互动消息DAO接口
 * 支持互动消息的完整CRUD操作、未读管理、历史查询等功能
 * 
 * @author PAI4J Team
 */
@Repository
public interface IInteractionMessageDAO extends JpaSpecificationExecutor<InteractionMessageEntity>, JpaRepository<InteractionMessageEntity, Long> {

    /**
     * 查询两个用户之间的所有互动消息
     * 
     * @param sender 发送者账号
     * @param receiver 接收者账号
     * @return 互动消息列表
     */
    @Query(value = "select distinct mess from InteractionMessageEntity mess where "
            + "(mess.sender = :sender or mess.receiver = :receiver) and "
            + "(mess.receiver = :sender or mess.sender = :sender) order by mess.id desc")
    List<InteractionMessageEntity> findAllBySenderAndReceiver(@Param("sender") String sender, 
                                                               @Param("receiver") String receiver);

    /**
     * 模糊查询互动消息
     * 
     * @param message 消息内容关键字
     * @param pageable 分页参数
     * @return 互动消息分页结果
     */
    Page<InteractionMessageEntity> findAllByMessageLike(String message, Pageable pageable);

    /**
     * 查询指定时间范围内两个用户之间的互动消息
     * 
     * @param sourceUserId 源用户ID
     * @param targetUserId 目标用户ID
     * @param startDate 开始时间
     * @param endDate 结束时间
     * @param pageable 分页参数
     * @return 互动消息分页结果
     */
    @Query(value = "select mess from InteractionMessageEntity mess " +
                    "where ((mess.sender = :sourceUserId and mess.receiver = :targetUserId) or " +
                    "(mess.sender = :targetUserId and mess.receiver = :sourceUserId)) " +
                    "and mess.sendDate between :startDate and :endDate " +
                    "order by mess.sendDate desc")
    Page<InteractionMessageEntity> findAllBySenderAndReceiverAndSendDateBefore(@Param("sourceUserId") String sourceUserId,
                                                                        @Param("targetUserId") String targetUserId,
                                                                        @Param("startDate") Date startDate,
                                                                        @Param("endDate") Date endDate,
                                                                        Pageable pageable);
    
    /**
     * 查询接收者的互动消息列表（分页，按发送时间倒序）
     * 用于用户查看自己收到的所有互动通知
     * 
     * @param receiver 接收者账号
     * @param pageable 分页参数
     * @return 互动消息分页结果
     */
    @Query("select mess from InteractionMessageEntity mess " +
           "where mess.receiver = :receiver " +
           "order by mess.sendDate desc")
    Page<InteractionMessageEntity> findByReceiverOrderBySendDateDesc(@Param("receiver") String receiver, 
                                                                      Pageable pageable);
    
    /**
     * 查询接收者的未读互动消息列表（分页，按发送时间倒序）
     * 
     * @param receiver 接收者账号
     * @param pageable 分页参数
     * @return 未读互动消息分页结果
     */
    @Query("select mess from InteractionMessageEntity mess " +
           "where mess.receiver = :receiver and mess.isRead = false " +
           "order by mess.sendDate desc")
    Page<InteractionMessageEntity> findUnreadByReceiverOrderBySendDateDesc(@Param("receiver") String receiver, 
                                                                            Pageable pageable);
    
    /**
     * 统计接收者的未读互动消息总数
     * 
     * @param receiver 接收者账号
     * @return 未读消息数量
     */
    @Query("select count(mess) from InteractionMessageEntity mess " +
           "where mess.receiver = :receiver and mess.isRead = false")
    long countUnreadByReceiver(@Param("receiver") String receiver);
    
    /**
     * 批量标记指定ID的互动消息为已读
     * 
     * @param messageIds 消息ID列表
     * @param receiver 接收者账号（用于安全验证）
     * @return 更新的记录数
     */
    @Modifying
    @Transactional
    @Query("update InteractionMessageEntity mess " +
           "set mess.isRead = true, mess.updateDate = current_timestamp " +
           "where mess.id in :messageIds and mess.receiver = :receiver and mess.isRead = false")
    int markMessagesAsReadByIds(@Param("messageIds") List<Long> messageIds, 
                                 @Param("receiver") String receiver);
    
    /**
     * 标记接收者的所有互动消息为已读
     * 
     * @param receiver 接收者账号
     * @return 更新的记录数
     */
    @Modifying
    @Transactional
    @Query("update InteractionMessageEntity mess " +
           "set mess.isRead = true, mess.updateDate = current_timestamp " +
           "where mess.receiver = :receiver and mess.isRead = false")
    int markAllMessagesAsReadByReceiver(@Param("receiver") String receiver);
    
    /**
     * 标记接收者的指定类型所有互动消息为已读
     * 用于一键已读功能，支持按消息类型筛选
     * 
     * @param receiver 接收者账号
     * @param messageType 消息类型
     * @return 更新的记录数
     */
    @Modifying
    @Transactional
    @Query("update InteractionMessageEntity mess " +
           "set mess.isRead = true, mess.updateDate = current_timestamp " +
           "where mess.receiver = :receiver and mess.messageType = :messageType and mess.isRead = false")
    int markAllMessagesAsReadByReceiverAndType(@Param("receiver") String receiver, 
                                                @Param("messageType") Integer messageType);
    
    /**
     * 根据消息类型查询接收者的互动消息（分页）
     * 支持按类型过滤互动消息，例如只查看点赞、评论等特定类型
     * 
     * @param receiver 接收者账号
     * @param type 消息类型
     * @param pageable 分页参数
     * @return 互动消息分页结果
     */
    @Query("select mess from InteractionMessageEntity mess " +
           "where mess.receiver = :receiver and mess.messageType = :messageType " +
           "order by mess.sendDate desc")
    Page<InteractionMessageEntity> findByReceiverAndMessageTypeOrderBySendDateDesc(@Param("receiver") String receiver,
                                                                                   @Param("messageType") Integer messageType,
                                                                                   Pageable pageable);
    
    /**
     * 统计接收者的指定类型未读消息数量
     * 
     * @param receiver 接收者账号
     * @param type 消息类型
     * @return 未读消息数量
     */
    @Query("select count(mess) from InteractionMessageEntity mess " +
           "where mess.receiver = :receiver and mess.messageType = :messageType and mess.isRead = false")
    long countUnreadByReceiverAndMessageType(@Param("receiver") String receiver,
                                             @Param("messageType") Integer messageType);
    
    /**
     * 查询最近N天接收者的互动消息（支持未读过滤）
     * 
     * @param receiver 接收者账号
     * @param afterDate 起始日期
     * @param unreadOnly 是否只查询未读
     * @param pageable 分页参数
     * @return 互动消息分页结果
     */
    @Query("select mess from InteractionMessageEntity mess " +
           "where mess.receiver = :receiver " +
           "and mess.sendDate >= :afterDate " +
           "and (:unreadOnly = false or mess.isRead = false) " +
           "order by mess.sendDate desc")
    Page<InteractionMessageEntity> findByReceiverAfterDate(@Param("receiver") String receiver,
                                                            @Param("afterDate") Date afterDate,
                                                            @Param("unreadOnly") boolean unreadOnly,
                                                            Pageable pageable);
    
    /**
     * 检查消息是否已存在（幂等性检查）
     * 用于防止重复消息入库
     * 
     * @param messageUuid 消息唯一标识
     * @return true=消息已存在，false=消息不存在
     */
    boolean existsByMessageUuid(String messageUuid);
    
    /**
     * 根据消息唯一标识查询消息
     * 
     * @param messageUuid 消息唯一标识
     * @return 互动消息实体
     */
    InteractionMessageEntity findByMessageUuid(String messageUuid);
}